package com.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easyCode.feature.mybaits.CustomPage;
import com.manager.entity.dao.Manager;
import com.manager.entity.dto.ManagerDto;
import com.manager.entity.dto.SdkManagerInfoDto;
import com.manager.entity.vo.ManagerVo;
import com.manager.exception.ManagerException;
import com.manager.mapper.ManagerMapper;
import com.manager.service.ICampusService;
import com.manager.service.IManagerService;
import com.security.client.AuthClient;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;

import static com.manager.constants.ManagerServiceConstants.*;
import static com.manager.entity.factory.ManagerFactory.MANAGER_CONVERTER;

@Service
@RequiredArgsConstructor
@Slf4j
public class ManagerServiceImpl extends ServiceImpl<ManagerMapper, Manager> implements IManagerService, UserDetailsService {
    @Autowired
    private ICampusService iCampusService;
    private final PasswordEncoder passwordEncoder;
    private final AuthClient authClient;

    @GlobalTransactional
    @Override
    public Integer saveManager(ManagerVo managerVo) {
        iCampusService.checkExist(managerVo.getCId());
        Manager manager = MANAGER_CONVERTER.toManager(managerVo);
        Manager.nameRepeatCheck(manager,this);
        manager.setPwd(passwordEncoder.encode(manager.getPassword()));
        save(manager);
        authClient.registerUser(managerVo.getAccount(), MANAGER_SERVICE_NAME, COMMON_MANAGER_ROLE_NAME);
        return manager.getId();
    }

    @Override
    public ManagerDto getManagerById(Integer id) {
        Manager manager = getById(id);
        return MANAGER_CONVERTER.toManagerDto(manager);
    }

    @Override
    public List<ManagerDto> listManager(String queryExample, CustomPage customPage) {
        List<Manager> managerList = CustomPage.getResult(customPage, new Manager(), this,
                ObjectUtils.isEmpty(queryExample)?null:
                        new QueryWrapper<Manager>().like("account",queryExample));
        return MANAGER_CONVERTER.toListManagerDto(managerList);
    }

    @GlobalTransactional
    @Override
    public void delManagerById(Integer id) {
        Manager manager = getById(id);
        if(manager==null){
            return;
        }
        if(Objects.equals(manager.getIdentity(), SUPER_MANAGER)){
            throw new ManagerException("超级管理员无权删除");
        }
        authClient.deleteUser(manager.getRealName(), MANAGER_SERVICE_NAME);
        removeById(id);
    }

    @Override
    public ManagerDto getManagerByName(String name) {
        Manager manager = getOne(new QueryWrapper<Manager>().eq("account",name));
        return MANAGER_CONVERTER.toManagerDto(manager);
    }

    /**
     *  改变管理员所属校区
     */
    @Override
    public Boolean changeManagerCampus(Integer campusId,Integer managerId) {
        iCampusService.checkExist(campusId);
        return updateById(Manager.builder().id(managerId).cId(campusId).build());
    }

    @Override
    public SdkManagerInfoDto loadByName(String userRealName) {
        if(StringUtils.isEmpty(userRealName)){
            return null;
        }
        Manager manager = getOne(new QueryWrapper<Manager>().eq("account", userRealName));
        return manager==null?null:SdkManagerInfoDto.builder().cId(manager.getCId()).enabled(manager.isEnabled()).id(manager.getId()).extra(manager.getIdentity()).build();
    }

    @Override
    public boolean enableOrDisableManager(Integer managerId, Integer enable) {
        Manager manager = getById(managerId);
        if(manager==null){
            return true;
        }
        if(Objects.equals(manager.getIdentity(), SUPER_MANAGER)){
            throw new ManagerException("无权访问");
        }
        return updateById(Manager.builder().id(managerId).enable(enable).build());
    }

    @Override
    public ManagerDto getSelf() {
        return MANAGER_CONVERTER.toManagerDto(Manager.getCurrentVisit());
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return getOne(new QueryWrapper<Manager>().eq("account", username));
    }
}
